/**
 * <p>Copyright:Copyright(c) 2013</p>
 * <p>Company:上海中信信息发展股份有限公司</p>
 * <p>包名:ces.framework.utils</p>
 * <p>文件名:JsonUtil.java</p>
 * <p>类更新历史信息</p>
 * @todo chanlong(陈龙) 创建于 2013年12月28日 下午12:03:59
 */
package org.framework.common.ext.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.framework.common.api.support.json.JsonMapperSupport;
import org.framework.common.ext.util.DateUtil.DatePattern;
import org.jboss.logging.Logger;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

/**
 * JSON格式工具类.
 * <p>描述:处理JSON格式数据</p>
 * <p>Company:上海中信信息发展股份有限公司</p>
 * @author chanlong(陈龙)
 * @date 2013年12月28日  下午12:03:59
 * @version 1.0.2013.
 */
public class JsonUtil {
	
	private static Logger log = Logger.getLogger(JsonUtil.class);
	
	private static ObjectMapper mapper = new JsonMapperSupport();
	
	/**
	 * 获取JSON处理器.
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2013年12月28日  下午12:05:55
	 */
	public static ObjectMapper getJsonProcesser(){
		return mapper;
	}
	
	/**
	 * 根据json字符串获取对应的实体对象.
	 * @param json “JSON”格式的字符串
	 * @param cls 实体对象类（处理json数组时，此处传入实体对象数组）
	 * @return
	 * @throws JsonParseException
	 * @throws JsonMappingException
	 * @throws IOException
	 * @author chanlong(陈龙)
	 * @date 2013年12月28日  下午12:09:07
	 */
	public static <T> T getBean(final String json, final Class<T> cls) {
		try {
			mapper.enableDefaultTyping();
			
			T bean = mapper.readValue(json, cls);
			
			return bean;
		} catch (JsonParseException e) {
			e.printStackTrace();
			log.error("解析JSON失败：", e);
			return null;
		} catch (JsonMappingException e) {
			e.printStackTrace();
			log.error("映射JSON失败：", e);
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			log.error("转换JSON失败：", e);
			return null;
		}
	}
	
	/**
	 * 根据json字符串获取对应的实体对象.
	 * @param json “JSON”格式的字符串
	 * @param cls 实体对象类（处理json数组时，此处传入实体对象数组）
	 * @param module
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年2月14日 上午8:34:31
	 */
	public static <T> T getBean(final String json, final Class<T> cls, final SimpleModule module) {
		mapper.registerModule(module);
		return getBean(json, cls);
	}
	
	/**
	 * 将要处理的json对象输出到前台页面.
	 * @param response HTTP响应对象
	 * @param obj 要处理的json对象
	 * @throws IOException
	 * @author chanlong(陈龙)
	 * @date 2013年12月28日  下午12:26:31
	 */
	public static void write(final HttpServletResponse response, final Object obj) throws IOException{
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();
		mapper.writeValue(writer, obj);
		writer.close();
	}
	
	/**
	 * 将对象转换成json字符串
	 * @param obj
	 * @return
	 * @throws JsonProcessingException
	 */
	public static String serialize(final Object obj) {
		try {
			/*if(obj.getClass().isArray()){
				mapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
			}else{
				mapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, false);
			}*/
			return mapper.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			log.error("序列化对象失败：", e);
			return null;
		}
	}
	
	public static String serialize(final Object obj, final DatePattern pattern) {
		DateFormat format = new SimpleDateFormat(pattern.value());
		mapper.setDateFormat(format);
		return serialize(obj);
	}
	
	/**
	 * JSON字符串反序列化.
	 * @param json
	 * @param cls
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月21日 上午10:40:16
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> deserialize(final String json) {
		try {
			return mapper.readValue(json, Map.class);
		} catch (JsonParseException e) {
			e.printStackTrace();
			log.error("解析JSON失败：", e);
			return null;
		} catch (JsonMappingException e) {
			e.printStackTrace();
			log.error("映射JSON失败：", e);
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			log.error("转换JSON失败：", e);
			return null;
		}
	}
	
	/**
	 * JSON字符串反序列化.
	 * @param json
	 * @param cls
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月21日 上午10:40:16
	 */
	public static <T> T deserialize(final String json, final Class<T> cls) {
		try {
			return mapper.readValue(json, getTypeReference(Map.class));
		} catch (JsonParseException e) {
			e.printStackTrace();
			log.error("解析JSON失败：", e);
			return null;
		} catch (JsonMappingException e) {
			e.printStackTrace();
			log.error("映射JSON失败：", e);
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			log.error("转换JSON失败：", e);
			return null;
		}
	}
	
	/**
	 * 获取类型应用.
	 * @param cls
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月21日 上午10:39:39
	 */
	public static <T> TypeReference<T> getTypeReference(Class<T> cls) {
		return new TypeReference<T>() {};
	}
	
	public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
		String json = "{\"obj\":{\"session\":\"4fd8ce4b-494e-4ae6-a19e-84a8a5966d17\",\"calleeDisplay\":\"18616584947\",\"callerDisplay\":\"13699996666\"},\"code\":200}";
		System.out.println(deserialize(json, Map.class));
	}
}
